/*  Pattern based natural language processing tools for Estonian.
    Copyright (C) 2013 University of Tartu

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PATNLP_RULE_HPP_
#define _PATNLP_RULE_HPP_

#include <PatNlp.hpp>
#include <DocCover.hpp>
#include <Cover.hpp>
#include <Corpus.hpp>

namespace patnlp
{

typedef std::pair<long, std::string> Rule;
typedef std::vector<Rule> Conjunction;
typedef std::vector<Conjunction> Disjunction;

typedef std::map<Rule, OrderedDocCover> RuleOrderedDocCover;
typedef std::map<Rule, OrderedCover> RuleOrderedCover;

/// Extract Rules from the document with their covers.
/// @param document: The document the rules will be extracted from.
/// @param radius: Context radius to use for creating the rules.
std::map<Rule, OrderedDocCover> doc_basic_rule_covers(Document const& document, long const radius=2);

/// Extract rules from the corpus with their covers.
/// @param corpus: The corpus of documents the rules will be extracted from.
/// @param radius: Context radius to use for creating the rules.
std::map<Rule, OrderedCover> basic_rule_covers(Corpus const& corpus, long const radius=2);

/// Extract full specific conjunctions from a single document.
std::set<Conjunction> doc_full_conjunctions(Document const& document, long const radius);

/// Extract full specific conjunctions from corpus.
std::vector<Conjunction> full_conjunctions(Corpus const& corpus, long const radius=2);

/// Count the number of different basic rules in Document.
std::map<Rule, long> doc_rule_count(Document const& document, long const radius=2);

/// Count the number of different basic rules in Corpus.
std::map<Rule, long> corpus_rule_count(Corpus const& corpus, long const radius=2);

/// Create conjunction pairs
std::vector<Conjunction> conjunction_pairs(std::vector<Conjunction> const& A, std::vector<Conjunction> const& B);

/// Unique conjunctions
std::vector<Conjunction> unique_conjunctions(std::vector<Conjunction> const& A);

/// Compute the cover of a conjunction.
OrderedCover conjunction_cover(Conjunction const& c, std::map<Rule, OrderedCover> const& basic_covers);


/// Reorder a list of conjunctions according to recall.
std::vector<Conjunction> reorder_recall(std::vector<Conjunction> const& conjunctions,
                                        std::map<Rule, OrderedCover> const& basic_covers,
                                        OrderedCover const& true_cover);

} //namespace patnlp

#endif
